#include "Customer.hh"
#include "Account.hh"
#include "Utilities.hh"
#include "main.hh"
#include <algorithm>
#include <fstream>
#include <numeric>
#include <functional>

Customer::Customer(const std::string& customerName) : name(customerName) {}

Customer::~Customer() {
    for (auto account : accounts) {
        delete account;
    }
}

std::string Customer::getName() const {
    return name;
}

const std::vector<Account*>& Customer::getAccounts() const {
    return accounts;
}

void Customer::addAccount(Account* account) {
    if (account) {
        accounts.push_back(account);
    }
}

Account* Customer::findAccountById(const std::string& accountId) const {
    auto it = std::find_if(accounts.begin(), accounts.end(), 
        [&accountId](Account* a) { return a->getAccountId() == accountId; });
    
    return (it != accounts.end()) ? *it : nullptr;
}

void Customer::displayCustomerInfo() const {
    std::cout << "\n===== Customer: " << name << " =====\n";
    std::cout << "This customer has the following accounts:\n\n";
    
    for (size_t i = 0; i < accounts.size(); ++i) {
        std::cout << (i + 1) << ". " << accounts[i]->getAccountType() << " Account: " 
                  << accounts[i]->getAccountId() << "\n";
        std::cout << "   Balance: " << Utilities::formatCurrency(accounts[i]->getBalance()) << "\n\n";
    }
}

void Customer::generateCustomerReport(const std::string& filename) const {
    std::ofstream outFile(filename);
    if (!outFile) {
        std::cerr << "Error: Unable to create report file.\n";
        return;
    }

    outFile << "===== Customer Report: " << name << " =====\n";
    outFile << "Total Accounts: " << accounts.size() << "\n";
    outFile << "Total Balance: " << Utilities::formatCurrency(
        std::accumulate(accounts.begin(), accounts.end(), 0.0, 
            [](double sum, Account* a) { return sum + a->getBalance(); })) << "\n\n";
    
    outFile << "Account Details:\n";
    for (const auto& account : accounts) {
        outFile << "Account Type: " << account->getAccountType() << "\n";
        outFile << "Account ID: " << account->getAccountId() << "\n";
        outFile << "Balance: " << Utilities::formatCurrency(account->getBalance()) << "\n\n";
    }

    outFile << "Transaction History:\n";
    for (const auto& account : accounts) {
        outFile << "Transactions for Account: " << account->getAccountId() << "\n";
        for (const auto& t : account->getTransactions()) {
            outFile << t << "\n";
        }
        outFile << "\n";
    }

    outFile.close();
}